1
2
3
4 package joeq.Linker.ELF;
5
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.Iterator;
9 import java.util.LinkedList;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Set;
13 import java.util.SortedMap;
14 import java.util.TreeMap;
15 import java.io.IOException;
16 import java.io.UnsupportedEncodingException;
17 import jwutil.collections.AppendIterator;
18 import jwutil.strings.Strings;
19 import jwutil.util.Assert;
20
21 /***
22 * Defines a section in an ELF file.
23 *
24 * @author John Whaley <jwhaley@alum.mit.edu>
25 * @version $Id: Section.java 1941 2004-09-30 03:37:06Z joewhaley $
26 */
27 public abstract class Section implements ELFConstants {
28
29 public static final String DEFAULT_ENCODING = "ISO-8859-1";
30
31 protected String name;
32 protected int index;
33 protected int flags;
34 protected int addr;
35
36 public int getIndex() { return index; }
37 public String getName() { return name; }
38 public abstract int getType();
39 public int getFlags() { return flags; }
40 public int getAddr() { return addr; }
41 public abstract int getSize();
42 public abstract int getLink();
43 public abstract int getInfo();
44 public abstract int getAddrAlign();
45 public abstract int getEntSize();
46
47 public void setIndex(int index) { this.index = index; }
48 public void setName(String name) { this.name = name; }
49 public void setAddr(int addr) { this.addr = addr; }
50 public void setWrite() { this.flags |= SHF_WRITE; }
51 public void clearWrite() { this.flags &= ~SHF_WRITE; }
52 public void setAlloc() { this.flags |= SHF_ALLOC; }
53 public void clearAlloc() { this.flags &= ~SHF_ALLOC; }
54 public void setExecInstr() { this.flags |= SHF_EXECINSTR; }
55 public void clearExecInstr() { this.flags &= ~SHF_EXECINSTR; }
56
57 public void writeHeader(ELF file, int offset) throws IOException {
58 file.write_sectionname(this.getName());
59 file.write_word(this.getType());
60 file.write_word(this.getFlags());
61 file.write_addr(this.getAddr());
62 file.write_off(offset);
63 file.write_word(this.getSize());
64 file.write_word(this.getLink());
65 file.write_word(this.getInfo());
66 file.write_word(this.getAddrAlign());
67 file.write_word(this.getEntSize());
68 }
69
70 public abstract void writeData(ELF file) throws IOException;
71 public abstract void load(UnloadedSection s, ELF file) throws IOException;
72
73 /*** Creates new Section */
74 protected Section(String name, int flags, int addr) {
75 this.name = name; this.flags = flags; this.addr = addr;
76 }
77
78 protected Section(int flags, int addr) {
79 this.flags = flags; this.addr = addr;
80 }
81
82 public static class UnloadedSection {
83
84 int sectionNameIndex;
85 int type;
86 int flags;
87 int addr;
88 int offset;
89 int size;
90 int link;
91 int info;
92 int addralign;
93 int entsize;
94
95 public UnloadedSection(ELF file) throws IOException {
96 readHeader(file);
97 }
98
99 public void readHeader(ELF file) throws IOException {
100 this.sectionNameIndex = file.read_word();
101 this.type = file.read_word();
102 this.flags = file.read_word();
103 this.addr = file.read_addr();
104 this.offset = file.read_off();
105 this.size = file.read_word();
106 this.link = file.read_word();
107 this.info = file.read_word();
108 this.addralign = file.read_word();
109 this.entsize = file.read_word();
110 }
111
112 public Section parseHeader() throws IOException {
113 switch (type) {
114 case SHT_NULL: {
115 if (this.flags != 0)
116 System.err.println("Warning! Null section flags is not 0: "+this.flags);
117 if (this.addr != 0)
118 System.err.println("Warning! Null section addr is not 0: "+this.addr);
119 if (this.offset != 0)
120 System.err.println("Warning! Null section offset is not 0: "+this.offset);
121 if (this.size != 0)
122 System.err.println("Warning! Null section size is not 0: "+this.size);
123 if (this.link != SHN_UNDEF)
124 System.err.println("Warning! Null section link is not SHN_UNDEF: "+this.link);
125 if (this.info != 0)
126 System.err.println("Warning! Null section info is not 0: "+this.info);
127 if (this.addralign != 0)
128 System.err.println("Warning! Null section addralign is not 0: "+this.addralign);
129 if (this.entsize != 0)
130 System.err.println("Warning! Null section entsize is not 0: "+this.entsize);
131 return NullSection.INSTANCE;
132 }
133 case SHT_PROGBITS: {
134 Assert._assert(this.link == SHN_UNDEF);
135 Assert._assert(this.info == 0);
136 Assert._assert(this.entsize == 0);
137 return ProgBitsSectionImpl.empty(this.flags, this.addr, this.addralign);
138 }
139 case SHT_SYMTAB: {
140 Assert._assert(this.addralign == 4);
141 Assert._assert(this.entsize == SymbolTableEntry.getEntrySize());
142 return SymTabSection.empty(this.flags, this.addr);
143 }
144 case SHT_STRTAB: {
145 if (this.link != SHN_UNDEF)
146 System.err.println("Warning! Strtab section link is not SHN_UNDEF: "+this.link);
147 if (this.info != 0)
148 System.err.println("Warning! Strtab section info is not 0: "+this.info);
149 if (this.addralign != 1)
150 System.err.println("Warning! Strtab section addralign is not 0: "+this.addralign);
151 if (this.entsize != 0)
152 System.err.println("Warning! Strtab section entsize is not 0: "+this.entsize);
153 return StrTabSection.empty(this.flags, this.addr);
154 }
155 case SHT_RELA:
156 case SHT_HASH:
157 case SHT_DYNAMIC:
158 case SHT_DYNSYM: {
159 Assert.TODO(); return null;
160 }
161 case SHT_NOTE: {
162 if (this.link != SHN_UNDEF)
163 System.err.println("Warning! Note section link is not SHN_UNDEF: "+this.link);
164 if (this.info != 0)
165 System.err.println("Warning! Note section info is not 0: "+this.info);
166 if (this.addralign != 1)
167 System.err.println("Warning! Note section addralign is not 0: "+this.addralign);
168 if (this.entsize != 0)
169 System.err.println("Warning! Note section entsize is not 0: "+this.entsize);
170 return NoteSection.empty(this.flags, this.addr);
171 }
172 case SHT_NOBITS: {
173 if (this.link != SHN_UNDEF)
174 System.err.println("Warning! Nobits section link is not SHN_UNDEF: "+this.link);
175 if (this.info != 0)
176 System.err.println("Warning! Nobits section info is not 0: "+this.info);
177 if (this.entsize != 0)
178 System.err.println("Warning! Nobits section entsize is not 0: "+this.entsize);
179 return NoBitsSection.empty(this.flags, this.addr, this.size, this.addralign);
180 }
181 case SHT_REL:
182 Assert._assert(this.addralign == 4);
183 Assert._assert(this.entsize == RelocEntry.getEntrySize());
184 return RelSection.empty(this.flags, this.addr);
185 case SHT_SHLIB:
186 default:
187
188 throw new IOException("bad section type: "+Strings.hex(type));
189 }
190 }
191
192 }
193
194 public abstract static class FakeSection extends Section {
195
196 FakeSection(String name, int index) { super(name, 0, 0); this.index = index; }
197 public int getEntSize() { Assert.UNREACHABLE(); return 0; }
198 public int getInfo() { Assert.UNREACHABLE(); return 0; }
199 public int getAddrAlign() { Assert.UNREACHABLE(); return 0; }
200 public int getLink() { Assert.UNREACHABLE(); return 0; }
201 public int getSize() { Assert.UNREACHABLE(); return 0; }
202 public int getType() { Assert.UNREACHABLE(); return 0; }
203 public int getFlags() { Assert.UNREACHABLE(); return 0; }
204 public int getAddr() { Assert.UNREACHABLE(); return 0; }
205 public int getIndex() { return index; }
206 public void setName(String name) { Assert.UNREACHABLE(); }
207 public void setAddr(int addr) { Assert.UNREACHABLE(); }
208 public void setWrite() { Assert.UNREACHABLE(); }
209 public void clearWrite() { Assert.UNREACHABLE(); }
210 public void setAlloc() { Assert.UNREACHABLE(); }
211 public void clearAlloc() { Assert.UNREACHABLE(); }
212 public void setExecInstr() { Assert.UNREACHABLE(); }
213 public void clearExecInstr() { Assert.UNREACHABLE(); }
214 public void writeData(ELF file) throws IOException {
215 Assert.UNREACHABLE();
216 }
217 public void load(UnloadedSection s, ELF file) throws IOException {
218 Assert.UNREACHABLE();
219 }
220
221 }
222
223 public static class AbsSection extends FakeSection {
224 public static final AbsSection INSTANCE = new AbsSection();
225 private AbsSection() { super("ABS", SHN_ABS); }
226 }
227
228 public static class NullSection extends Section {
229 public static final NullSection INSTANCE = new NullSection();
230 private NullSection() { super("", 0, 0); }
231 public int getIndex() { return 0; }
232 public int getType() { return SHT_NULL; }
233 public int getSize() { return 0; }
234 public int getLink() { return SHN_UNDEF; }
235 public int getInfo() { return 0; }
236 public int getAddrAlign() { return 0; }
237 public int getEntSize() { return 0; }
238 public void setIndex(int index) { Assert._assert(index == 0); }
239 public void setName(String name) { Assert._assert(name.equals("")); }
240 public void setAddr(int addr) { Assert._assert(addr == 0); }
241 public void setOffset(int offset) { Assert._assert(offset == 0); }
242 public void setWrite() { Assert.UNREACHABLE(); }
243 public void setAlloc() { Assert.UNREACHABLE(); }
244 public void setExecInstr() { Assert.UNREACHABLE(); }
245 public void writeData(ELF file) throws IOException { }
246 public void load(UnloadedSection s, ELF file) throws IOException { }
247 }
248
249 public abstract static class ProgBitsSection extends Section {
250 public ProgBitsSection(String name, int flags, int addr) {
251 super(name, flags, addr);
252 }
253 protected ProgBitsSection(int flags, int addr) {
254 super(flags, addr);
255 }
256 public final int getType() { return SHT_PROGBITS; }
257 public final int getLink() { return SHN_UNDEF; }
258 public final int getInfo() { return 0; }
259 public final int getEntSize() { return 0; }
260
261 }
262
263 public static class ProgBitsSectionImpl extends ProgBitsSection {
264 protected int addralign;
265 protected byte[] data;
266 public ProgBitsSectionImpl(String name, int flags, int addr, int addralign, byte[] data) {
267 super(name, flags, addr);
268 this.addralign = addralign;
269 this.data = data;
270 }
271 protected ProgBitsSectionImpl(int flags, int addr, int addralign) {
272 super(flags, addr);
273 this.addralign = addralign;
274 }
275 public final int getSize() { return data.length; }
276 public final int getAddr() { return addr; }
277 public final int getAddrAlign() { return addralign; }
278 public void writeData(ELF file) throws IOException {
279 file.write_bytes(data);
280 }
281
282 public static ProgBitsSectionImpl empty(int flags, int addr, int addralign) {
283 return new ProgBitsSectionImpl(flags, addr, addralign);
284 }
285
286 public void load(UnloadedSection s, ELF file) throws IOException {
287 if (s.sectionNameIndex != 0) {
288 StrTabSection ss = file.getSectionHeaderStringTable();
289 if (ss == null) throw new IOException();
290 this.name = ss.getString(s.sectionNameIndex);
291 }
292 this.data = new byte[s.size];
293 file.set_position(s.offset);
294 file.read_bytes(data);
295 }
296 }
297
298 public static class SymTabSection extends Section {
299 List
300 StrTabSection stringTable;
301 public SymTabSection(String name, int flags, int addr, StrTabSection stringTable) {
302 super(name, flags, addr);
303 this.stringTable = stringTable;
304 this.localSymbols = new LinkedList(); this.globalSymbols = new LinkedList();
305 addSymbol(SymbolTableEntry.EmptySymbolTableEntry.INSTANCE);
306 }
307 protected SymTabSection(int flags, int addr) {
308 super(flags, addr);
309 }
310 public void addSymbol(SymbolTableEntry e) {
311 stringTable.addString(e.getName());
312 if (e.getBind() == SymbolTableEntry.STB_LOCAL) localSymbols.add(e);
313 else globalSymbols.add(e);
314 }
315 public int getSize() { return (localSymbols.size() + globalSymbols.size()) * SymbolTableEntry.getEntrySize(); }
316 public int getAddrAlign() { return 4; }
317 public final int getType() { return SHT_SYMTAB; }
318 public final int getLink() { return stringTable.getIndex(); }
319 public final int getInfo() { return localSymbols.size(); }
320 public final int getEntSize() { return SymbolTableEntry.getEntrySize(); }
321 public void setIndices() {
322 Iterator i = new AppendIterator(localSymbols.iterator(), globalSymbols.iterator());
323 int j=-1;
324 while (i.hasNext()) {
325 SymbolTableEntry e = (SymbolTableEntry)i.next();
326 e.setIndex(++j);
327 }
328 }
329 public SymbolTableEntry getSymbolTableEntry(int i) {
330 if (i < localSymbols.size()) return (SymbolTableEntry)localSymbols.get(i);
331 i -= localSymbols.size();
332 return (SymbolTableEntry)globalSymbols.get(i);
333 }
334 public void writeData(ELF file) throws IOException {
335 Iterator i = new AppendIterator(localSymbols.iterator(), globalSymbols.iterator());
336 while (i.hasNext()) {
337 SymbolTableEntry e = (SymbolTableEntry)i.next();
338 e.write(file, stringTable);
339 }
340 }
341
342 public static SymTabSection empty(int flags, int addr) {
343 return new SymTabSection(flags, addr);
344 }
345
346 public void load(UnloadedSection s, ELF file) throws IOException {
347 if (s.sectionNameIndex != 0) {
348 StrTabSection ss = file.getSectionHeaderStringTable();
349 if (ss == null) throw new IOException();
350 this.name = ss.getString(s.sectionNameIndex);
351 }
352 this.stringTable = (StrTabSection)file.getSection(s.link);
353 file.set_position(s.offset);
354 int n = s.size / this.getEntSize();
355 if (s.size % this.getEntSize() != 0) throw new IOException();
356 this.localSymbols = new LinkedList();
357 this.globalSymbols = new LinkedList();
358 while (--n >= 0) {
359 SymbolTableEntry e = SymbolTableEntry.read(file, this.stringTable);
360 this.addSymbol(e);
361 }
362 if (this.getInfo() != s.info) throw new IOException();
363 }
364
365 }
366
367 public static class DynSymSection extends Section {
368 List
369 StrTabSection stringTable;
370 public DynSymSection(String name, int flags, int addr, StrTabSection stringTable) {
371 super(name, flags, addr);
372 this.stringTable = stringTable;
373 this.localSymbols = new LinkedList(); this.globalSymbols = new LinkedList();
374 }
375 protected DynSymSection(int flags, int addr) {
376 super(flags, addr);
377 }
378 public void addSymbol(SymbolTableEntry e) {
379 stringTable.addString(e.getName());
380 if (e.getBind() == SymbolTableEntry.STB_LOCAL) localSymbols.add(e);
381 else globalSymbols.add(e);
382 }
383 public int getSize() { return (localSymbols.size() + globalSymbols.size()) * SymbolTableEntry.getEntrySize(); }
384 public int getAddrAlign() { return 4; }
385 public final int getType() { return SHT_DYNSYM; }
386 public final int getLink() { return stringTable.getIndex(); }
387 public final int getInfo() { return localSymbols.size(); }
388 public final int getEntSize() { return SymbolTableEntry.getEntrySize(); }
389 public SymbolTableEntry getSymbolTableEntry(int i) {
390 if (i < localSymbols.size()) return (SymbolTableEntry)localSymbols.get(i);
391 i -= localSymbols.size();
392 return (SymbolTableEntry)globalSymbols.get(i);
393 }
394 public void writeData(ELF file) throws IOException {
395 Iterator i = new AppendIterator(localSymbols.iterator(), globalSymbols.iterator());
396 while (i.hasNext()) {
397 SymbolTableEntry e = (SymbolTableEntry)i.next();
398 e.write(file, stringTable);
399 }
400 }
401
402 public static DynSymSection empty(int flags, int addr) {
403 return new DynSymSection(flags, addr);
404 }
405
406 public void load(UnloadedSection s, ELF file) throws IOException {
407 if (s.sectionNameIndex != 0) {
408 StrTabSection ss = file.getSectionHeaderStringTable();
409 if (ss == null) throw new IOException();
410 this.name = ss.getString(s.sectionNameIndex);
411 }
412 this.stringTable = (StrTabSection)file.getSection(s.link);
413 file.set_position(s.offset);
414 int n = s.size / this.getEntSize();
415 if (s.size % this.getEntSize() != 0) throw new IOException();
416 this.localSymbols = new LinkedList();
417 this.globalSymbols = new LinkedList();
418 while (--n >= 0) {
419 SymbolTableEntry e = SymbolTableEntry.read(file, this.stringTable);
420 this.addSymbol(e);
421 }
422 if (this.getInfo() != s.info) throw new IOException();
423 }
424
425 }
426
427 public static class StrTabSection extends Section {
428 protected Map
429 protected byte[] table;
430 public StrTabSection(String name, int flags, int addr) {
431 super(name, flags, addr);
432 string_map = new HashMap();
433 }
434 protected StrTabSection(int flags, int addr) {
435 super(flags, addr);
436 }
437 public final int getType() { return SHT_STRTAB; }
438 public final int getLink() { return SHN_UNDEF; }
439 public final int getInfo() { return 0; }
440 public final int getEntSize() { return 0; }
441
442 public final int getNumberOfEntries() { return string_map.size(); }
443
444 public void addString(String s) { string_map.put(s, null); }
445
446 public void super_pack() {
447
448 SortedMap tm = new TreeMap();
449 Iterator i = string_map.keySet().iterator();
450 while (i.hasNext()) {
451 String s = (String)i.next();
452 int l = -s.length();
453 Integer in = new Integer(l);
454 Set set = (Set)tm.get(in);
455 if (set == null)
456 tm.put(in, set = new HashSet());
457 set.add(s);
458 }
459
460 List string_set = new LinkedList();
461 i = tm.entrySet().iterator();
462 int index = 1;
463 while (i.hasNext()) {
464 Map.Entry e = (Map.Entry)i.next();
465 int in = -((Integer)e.getKey()).intValue();
466 if (in == 0) break;
467 Set set = (Set)e.getValue();
468 for (Iterator j=set.iterator(); j.hasNext(); ) {
469 String s1 = (String)j.next();
470 Assert._assert(s1.length() == in);
471 int index2;
472 for (Iterator k=string_set.iterator(); ; ) {
473 if (!k.hasNext()) {
474 index2 = index;
475 index += in + 1;
476 string_set.add(s1);
477 break;
478 }
479 String s2 = (String)k.next();
480 if (s2.length() == in) {
481 index2 = index;
482 index += in + 1;
483 string_set.add(s1);
484 break;
485 }
486 if (s2.endsWith(s1)) {
487
488 index2 = ((Integer)string_map.get(s2)).intValue();
489 index2 += s2.length();
490 index2 -= in;
491 break;
492 }
493 }
494 string_map.put(s1, new Integer(index2));
495 }
496 }
497
498 table = new byte[index];
499 i = string_map.entrySet().iterator();
500 while (i.hasNext()) {
501 Map.Entry e = (Map.Entry)i.next();
502 String s = (String)e.getKey();
503 if (e.getValue() == null) continue;
504 index = ((Integer)e.getValue()).intValue();
505
506
507 if (false) {
508
509
510 } else {
511 try {
512 byte[] b = s.getBytes(DEFAULT_ENCODING);
513 System.arraycopy(b, 0, table, index, b.length);
514 } catch (UnsupportedEncodingException x) { Assert.UNREACHABLE(); }
515 }
516 }
517 }
518
519 public void pack() {
520 int size = 1;
521 Iterator i = string_map.entrySet().iterator();
522 while (i.hasNext()) {
523 Map.Entry e = (Map.Entry)i.next();
524 String s = (String)e.getKey();
525 if (s.length() == 0) {
526 e.setValue(new Integer(0));
527 } else {
528 e.setValue(new Integer(size));
529 size += s.length() + 1;
530 }
531 }
532 if (size == 1) size = 0;
533
534 table = new byte[size];
535 int index = 1;
536 i = string_map.entrySet().iterator();
537 while (i.hasNext()) {
538 Map.Entry e = (Map.Entry)i.next();
539 String s = (String)e.getKey();
540 if (s.length() == 0) {
541 Assert._assert(((Integer)e.getValue()).intValue() == 0);
542 continue;
543 }
544
545
546 if (false) {
547
548
549 } else {
550 try {
551 byte[] b = s.getBytes(DEFAULT_ENCODING);
552 Assert._assert(b.length == s.length(), s);
553 System.arraycopy(b, 0, table, index, b.length);
554 } catch (UnsupportedEncodingException x) { Assert.UNREACHABLE(); }
555 }
556 Assert._assert(((Integer)e.getValue()).intValue() == index, s);
557 index += s.length() + 1;
558 }
559 Assert._assert(size == 0 || size == index);
560 }
561
562 public int getStringIndex(String s) {
563 Integer i = (Integer)string_map.get(s);
564 if (i == null)
565 return 0;
566 Assert._assert(getString(i.intValue()).equals(s), s);
567 return i.intValue();
568 }
569 public String getString(int i) {
570 int n=0;
571 for (;;) {
572 if (table[n+i] == '\0') break;
573 ++n;
574 }
575 try {
576 return new String(table, i, n, DEFAULT_ENCODING);
577 } catch (UnsupportedEncodingException x) { Assert.UNREACHABLE(); return null; }
578 }
579 public int getSize() { return table.length; }
580 public int getAddrAlign() { return 1; }
581 public void writeData(ELF file) throws IOException {
582 file.write_bytes(table);
583 }
584
585 public static StrTabSection empty(int flags, int addr) {
586 return new StrTabSection(flags, addr);
587 }
588
589 public void load(UnloadedSection s, ELF file) throws IOException {
590 this.table = new byte[s.size];
591 file.set_position(s.offset);
592 file.read_bytes(this.table);
593 if (s.sectionNameIndex != 0) {
594 StrTabSection ss = file.getSectionHeaderStringTable();
595 if (ss == null) throw new IOException();
596 this.name = ss.getString(s.sectionNameIndex);
597 }
598 }
599 }
600
601 public static class RelASection extends Section {
602 protected List
603 protected SymTabSection symbolTable;
604 protected Section targetSection;
605 public RelASection(String name, int flags, int addr, SymTabSection symbolTable, Section targetSection) {
606 super(name, flags, addr);
607 this.symbolTable = symbolTable; this.targetSection = targetSection;
608 this.relocs = new LinkedList();
609 }
610 protected RelASection(int flags, int addr) {
611 super(flags, addr);
612 }
613 public final int getType() { return SHT_RELA; }
614 public final int getLink() { return symbolTable.getIndex(); }
615 public final int getInfo() { return targetSection.getIndex(); }
616 public final int getEntSize() { return RelocAEntry.getEntrySize(); }
617 public int getSize() { return relocs.size() * RelocAEntry.getEntrySize(); }
618 public int getAddrAlign() { return 4; }
619 public void addReloc(RelocAEntry e) { relocs.add(e); }
620 public void writeData(ELF file) throws IOException {
621 Iterator i = relocs.iterator();
622 while (i.hasNext()) {
623 RelocAEntry e = (RelocAEntry)i.next();
624 e.write(file);
625 }
626 }
627
628 public static RelASection empty(int flags, int addr) {
629 return new RelASection(flags, addr);
630 }
631
632 public void load(UnloadedSection s, ELF file) throws IOException {
633 if (s.sectionNameIndex != 0) {
634 StrTabSection ss = file.getSectionHeaderStringTable();
635 if (ss == null) throw new IOException();
636 this.name = ss.getString(s.sectionNameIndex);
637 }
638 this.symbolTable = (SymTabSection)file.getSection(s.link);
639 this.targetSection = file.getSection(s.info);
640 int n = s.size / getEntSize();
641 if (n % getEntSize() != 0) throw new IOException();
642 this.relocs = new LinkedList();
643 file.set_position(s.offset);
644 while (--n >= 0) {
645 RelocAEntry e = (RelocAEntry)RelocAEntry.read(file, this.symbolTable);
646 this.addReloc(e);
647 }
648 }
649
650 }
651
652 public static class HashSection extends Section {
653 protected int sectionIndex;
654 public HashSection(String name, int flags, int addr, int sectionIndex) {
655 super(name, flags, addr);
656 this.sectionIndex = sectionIndex;
657 }
658 public final int getType() { return SHT_HASH; }
659 public final int getLink() { return sectionIndex; }
660 public final int getInfo() { return 0; }
661 public final int getEntSize() { return 0; }
662 public int getSize() { return 0; }
663 public int getAddrAlign() { return 0; }
664 public void writeData(ELF file) throws IOException {
665
666 }
667 public void load(UnloadedSection s, ELF file) throws IOException {
668
669 }
670
671 }
672
673 public static class DynamicSection extends Section {
674 protected int stringTableIndex;
675 public DynamicSection(String name, int flags, int addr, int stringTableIndex) {
676 super(name, flags, addr);
677 this.stringTableIndex = stringTableIndex;
678 }
679 public final int getType() { return SHT_DYNAMIC; }
680 public final int getLink() { return stringTableIndex; }
681 public final int getInfo() { return 0; }
682 public final int getEntSize() { return 0; }
683 public int getSize() { return 0; }
684 public int getAddrAlign() { return 0; }
685 public void writeData(ELF file) throws IOException {
686
687 }
688
689 public void load(UnloadedSection s, ELF file) throws IOException {
690 }
691
692 }
693
694 public static class NoteSection extends Section {
695 protected String notename;
696 protected byte[] notedesc;
697 protected int notetype;
698 public NoteSection(String sectionname, int flags, int addr, String notename, byte[] notedesc, int notetype) {
699 super(sectionname, flags, addr);
700 this.notename = notename; this.notedesc = notedesc; this.notetype = notetype;
701 }
702 protected NoteSection(int flags, int addr) {
703 super(flags, addr);
704 }
705 public final int getType() { return SHT_NOTE; }
706 public final int getLink() { return SHN_UNDEF; }
707 public final int getInfo() { return 0; }
708 public final int getEntSize() { return 0; }
709 protected int getNameLength() { return (notename.length()+4)&~3; }
710 public int getSize() { return 12 + getNameLength() + notedesc.length; }
711 public int getAddrAlign() { return 1; }
712 public void writeData(ELF file) throws IOException {
713 file.write_word(getNameLength());
714 file.write_word(notedesc.length);
715 file.write_word(notetype);
716 byte[] notename_b = new byte[getNameLength()];
717 if (false) {
718
719
720 } else {
721 try {
722 byte[] b = notename.getBytes(DEFAULT_ENCODING);
723 System.arraycopy(b, 0, notename_b, 0, b.length);
724 } catch (UnsupportedEncodingException x) { Assert.UNREACHABLE(); }
725 }
726 file.write_bytes(notename_b);
727 file.write_bytes(notedesc);
728 }
729
730 public static NoteSection empty(int flags, int addr) {
731 return new NoteSection(flags, addr);
732 }
733
734 public void load(UnloadedSection s, ELF file) throws IOException {
735 if (s.sectionNameIndex != 0) {
736 StrTabSection ss = file.getSectionHeaderStringTable();
737 if (ss == null) throw new IOException();
738 this.name = ss.getString(s.sectionNameIndex);
739 }
740 file.set_position(s.offset);
741 int nlength = file.read_word();
742 int dlength = file.read_word();
743 this.notetype = file.read_word();
744 byte[] notename_b = new byte[nlength];
745 file.read_bytes(notename_b);
746 try {
747 this.notename = new String(notename_b, DEFAULT_ENCODING);
748 } catch (UnsupportedEncodingException x) { Assert.UNREACHABLE(); }
749 this.notedesc = new byte[dlength];
750 file.read_bytes(notedesc);
751 if (this.getSize() != s.size) throw new IOException();
752 }
753 }
754
755 public static class NoBitsSection extends Section {
756 protected int size; protected int addralign;
757 public NoBitsSection(String name, int flags, int addr, int size, int addralign) {
758 super(name, flags, addr);
759 this.size = size; this.addralign = addralign;
760 }
761 protected NoBitsSection(int flags, int addr, int size, int addralign) {
762 super(flags, addr);
763 this.size = size; this.addralign = addralign;
764 }
765 public final int getType() { return SHT_NOBITS; }
766 public final int getLink() { return SHN_UNDEF; }
767 public final int getInfo() { return 0; }
768 public final int getEntSize() { return 0; }
769 public int getSize() { return size; }
770 public int getAddrAlign() { return addralign; }
771 public void writeData(ELF file) throws IOException { }
772
773 public static NoBitsSection empty(int flags, int addr, int size, int addralign) {
774 return new NoBitsSection(flags, addr, size, addralign);
775 }
776
777 public void load(UnloadedSection s, ELF file) throws IOException {
778 if (s.sectionNameIndex != 0) {
779 StrTabSection ss = file.getSectionHeaderStringTable();
780 if (ss == null) throw new IOException();
781 this.name = ss.getString(s.sectionNameIndex);
782 }
783 }
784 }
785
786 public static class RelSection extends Section {
787 protected List
788 protected SymTabSection symbolTable;
789 protected Section targetSection;
790 public RelSection(String name, int flags, int addr, SymTabSection symbolTable, Section targetSection) {
791 super(name, flags, addr);
792 this.symbolTable = symbolTable; this.targetSection = targetSection;
793 this.relocs = new LinkedList();
794 }
795 protected RelSection(int flags, int addr) {
796 super(flags, addr);
797 }
798 public final int getType() { return SHT_REL; }
799 public final int getLink() { return symbolTable.getIndex(); }
800 public final int getInfo() { return targetSection.getIndex(); }
801 public final int getEntSize() { return RelocEntry.getEntrySize(); }
802 public int getSize() { return relocs.size() * RelocEntry.getEntrySize(); }
803 public int getAddrAlign() { return 4; }
804 public void addReloc(RelocEntry e) { relocs.add(e); }
805 public void writeData(ELF file) throws IOException {
806 Iterator i = relocs.iterator();
807 while (i.hasNext()) {
808 RelocEntry e = (RelocEntry)i.next();
809 e.write(file);
810 }
811 }
812
813 public static RelSection empty(int flags, int addr) {
814 return new RelSection(flags, addr);
815 }
816
817 public void load(UnloadedSection s, ELF file) throws IOException {
818 if (s.sectionNameIndex != 0) {
819 StrTabSection ss = file.getSectionHeaderStringTable();
820 if (ss == null) throw new IOException();
821 this.name = ss.getString(s.sectionNameIndex);
822 }
823 this.symbolTable = (SymTabSection)file.getSection(s.link);
824 this.targetSection = file.getSection(s.info);
825 int n = s.size / getEntSize();
826 if (n % getEntSize() != 0) throw new IOException();
827 this.relocs = new LinkedList();
828 file.set_position(s.offset);
829 while (--n >= 0) {
830 RelocEntry e = RelocEntry.read(file, this.symbolTable);
831 this.addReloc(e);
832 }
833 }
834 }
835
836 public static int getHeaderSize() { return 40; }
837 }